package com.nantong.admin.controller;

import java.util.List;

import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import com.nantong.admin.annotation.PermissionRegister;
import com.nantong.admin.domain.SysRole;
import com.nantong.admin.domain.model.request.role.RoleSearch;
import com.nantong.admin.domain.model.response.role.SysRoleVo;
import com.nantong.admin.service.ISysRoleService;
import com.nantong.common.core.domain.R;
import com.nantong.common.mybatis.core.page.PageQuery;
import com.nantong.common.mybatis.core.page.TableDataInfo;

import org.springframework.web.bind.annotation.*;

/**
 * 角色管理
 *
 * @author nantong
 */
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/system/role")
@Tag(name = "角色管理", description = "角色管理相关接口")
@PermissionRegister(
    name = "角色管理", 
    key = "system:role", 
    type = 2,  // 2=菜单
    path = "role",
    component = "/views/Role/RoleView.vue",
    icon = "team",
    sortOrder = 2,
    parentKey = "system"  // 父菜单是system
)
public class SysRoleController {

    private final ISysRoleService roleService;

    /**
     * 获取角色列表
     */
    @GetMapping("/list")
    @Operation(summary = "获取角色列表", description = "获取系统角色列表")
    @SaCheckPermission("system:role:list")
    @PermissionRegister(
            name = "角色列表查询",
            key = "system:role:list",
            type = 3,  // 3=按钮
            remark = "查询角色数据列表"
    )
    public R<List<SysRole>> RoleSearch() {
        List<SysRole> roles = roleService.list();
        return R.ok(roles);
    }
    
    /**
     * 分页获取角色列表
     */
    @GetMapping("/page")
    @Operation(summary = "分页获取角色列表", description = "分页获取系统角色列表")
    @SaCheckPermission("system:role:page")
    @PermissionRegister(
            name = "角色分页查询",
            key = "system:role:page",
            type = 3,  // 3=按钮
            remark = "分页查询角色数据列表"
    )
    public TableDataInfo<SysRoleVo> page(RoleSearch search, PageQuery pageQuery) {
        return roleService.selectPageList(search, pageQuery);
    }

    /**
     * 获取角色详情
     */
    @GetMapping("/{roleId}")
    @Operation(summary = "获取角色详情", description = "根据角色ID获取角色详情")
    @SaCheckPermission("system:role:query")
    @PermissionRegister(
            name = "角色详情查询",
            key = "system:role:query",
            type = 3,  // 3=按钮
            remark = "查询角色数据详情"
    )
    public R<SysRole> getInfo(@PathVariable Long roleId) {
        SysRole role = roleService.getById(roleId);
        return R.ok(role);
    }

    /**
     * 新增角色
     */
    @PostMapping
    @Operation(summary = "新增角色", description = "新增系统角色")
    @SaCheckPermission("system:role:add")
    @PermissionRegister(
            name = "角色新增",
            key = "system:role:add",
            type = 3,  // 3=按钮
            remark = "新增角色数据"
    )
    public R<Void> add(@RequestBody SysRole role) {
        if (!roleService.checkRoleNameUnique(role)) {
            return R.fail("新增角色'" + role.getRoleName() + "'失败，角色名称已存在");
        }
        if (!roleService.checkRoleKeyUnique(role)) {
            return R.fail("新增角色'" + role.getRoleName() + "'失败，角色权限已存在");
        }
        roleService.save(role);
        return R.ok();
    }

    /**
     * 修改角色
     */
    @PutMapping
    @Operation(summary = "修改角色", description = "修改系统角色")
    @SaCheckPermission("system:role:edit")
    @PermissionRegister(
            name = "角色修改",
            key = "system:role:edit",
            type = 3,  // 3=按钮
            remark = "修改角色数据"
    )
    public R<Void> edit(@RequestBody SysRole role) {
        if (!roleService.checkRoleNameUnique(role)) {
            return R.fail("修改角色'" + role.getRoleName() + "'失败，角色名称已存在");
        }
        if (!roleService.checkRoleKeyUnique(role)) {
            return R.fail("修改角色'" + role.getRoleName() + "'失败，角色权限已存在");
        }
        roleService.updateById(role);
        return R.ok();
    }

    /**
     * 删除角色
     */
    @DeleteMapping("/{roleId}")
    @Operation(summary = "删除角色", description = "删除系统角色")
    @SaCheckPermission("system:role:delete")
    @PermissionRegister(
            name = "角色删除",
            key = "system:role:delete",
            type = 3,  // 3=按钮
            remark = "删除角色数据"
    )
    public R<Void> remove(@PathVariable Long roleId) {
        roleService.removeById(roleId);
        return R.ok();
    }

    /**
     * 获取角色权限ID列表
     */
    @GetMapping("/permissions/{roleId}")
    @Operation(summary = "获取角色权限ID列表", description = "获取角色拥有的权限ID列表")
    @SaCheckPermission("system:role:query")
    @PermissionRegister(
            name = "获取角色权限",
            key = "system:role:permissions",
            type = 3,  // 3=按钮
            remark = "查询角色权限数据"
    )
    public R<List<Long>> getRolePermissions(@PathVariable Long roleId) {
        List<Long> permissionIds = roleService.listPermissionIdsByRoleId(roleId);
        return R.ok(permissionIds);
    }

    /**
     * 分配角色权限
     */
    @PutMapping("/permissions/{roleId}")
    @Operation(summary = "分配角色权限", description = "为角色分配权限")
    @SaCheckPermission("system:role:edit")
    @PermissionRegister(
            name = "分配角色权限",
            key = "system:role:assign",
            type = 3,  // 3=按钮
            remark = "为角色分配权限"
    )
    public R<Void> assignPermissions(@PathVariable Long roleId, @RequestBody List<Object> permissionIds) {
        // 将前端传来的字符串或数字统一转换为Long，避免大整数精度丢失
        List<Long> longPermissionIds = permissionIds.stream()
                .map(id -> {
                    if (id instanceof String) {
                        return Long.parseLong((String) id);
                    } else if (id instanceof Number) {
                        return ((Number) id).longValue();
                    } else {
                        throw new IllegalArgumentException("权限ID格式不正确: " + id);
                    }
                })
                .toList();
        roleService.assignRolePermissions(roleId, longPermissionIds);
        return R.ok();
    }
}
